package com.niyue.sandbox.invokevis;

import java.util.LinkedList;
import java.util.List;

public class TreeNodeImpl implements TreeNode {
	private List<TreeNode> children;
	private String methodName;
	private int level;
	public String getMethodName() {
		return methodName;
	}

	public List<TreeNode> getChildren() {
		return children;
	}

	public void addChild(TreeNode childNode) {
		children.add(childNode);
	}

	public void setMethodName(String methodName) {
		this.methodName = methodName;
	}

	public int getLevel() {
		return level;
	}

	public void setLevel(int level) {
		this.level = level;
	}

	public TreeNodeImpl(String methodName, int level) {
		super();
		this.children = new LinkedList<TreeNode>();
		this.methodName = methodName;
		this.level = level;
	}

	public String toPlainText() {
		String callStack = "";
		for (int i = 0; i < level; i++) {
			callStack += "\t";				
		}			
		callStack += this.methodName + "\n";
		for(TreeNode subTreeNode : children){
			callStack += subTreeNode.toPlainText();
		}
		return callStack;
	}

	@Override
	public String toString() {
		return this.toPlainText();
	}

	public String toDot() {
		StringBuffer dotString = new StringBuffer();
		//if this is root node
		if(level == 0){
			dotString.append("digraph G{\n");
		}
		dotString.append("\t").append(getNodeName()).append("[").append("label=\"").append(getMethodName()).append("\"];\n");
		for(TreeNode subTreeNode : children){
			dotString.append("\t").append(getNodeName()).append(" -> ").append(subTreeNode.getNodeName()).append(";\n");
			dotString.append(subTreeNode.toDot());
		}
		if(level == 0){
			dotString.append("}");
		}
		return dotString.toString();
	}
	public String getNodeName(){
		return "node" + Math.abs(hashCode());
	}


	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((methodName == null) ? 0 : methodName.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		final TreeNodeImpl other = (TreeNodeImpl) obj;
		if (methodName == null) {
			if (other.methodName != null)
				return false;
		} else if (!methodName.equals(other.methodName))
			return false;
		return true;
	}

	public String toHtml() {
		StringBuffer htmlString = new StringBuffer();
		// root node
		if(level == 0){
			htmlString.append(htmlStart);
			htmlString.append("function treeInit() {\n"); 
			htmlString.append("tree = new YAHOO.widget.TreeView('treeDiv');\n");
			htmlString.append("var root = tree.getRoot();\n");			
			htmlString.append("var " + getNodeName() + " = new YAHOO.widget.TextNode('" + getMethodName() + "', root, false);\n"); 
		}		
		for(TreeNode subTreeNode : children){
			htmlString.append("var " + subTreeNode.getNodeName() + " = new YAHOO.widget.TextNode('" + subTreeNode.getMethodName() + "', " + getNodeName() + ", false);\n");
			htmlString.append(subTreeNode.toHtml());
		}
		if(level == 0){
			htmlString.append("tree.draw();\n}\n");
			htmlString.append(htmlEnd);
		}
		return htmlString.toString();
	}	
	
	public String toXml() {
		StringBuffer xmlString = new StringBuffer();
		//if this is root node
		if(level == 0){
			xmlString.append("<graph>\n");
		}
		xmlString.append("\t").append("<Node id=\"" + getNodeName()).append("\" prop=\"").append(getMethodName()).append("\"/>\n");
		for(TreeNode subTreeNode : children){
			xmlString.append(subTreeNode.toXml());
			xmlString.append("\t").append("<Edge fromID=\"" + getNodeName()).append("\" toID=\"").append(subTreeNode.getNodeName()).append("\"/>\n");
		}
		if(level == 0){
			xmlString.append("</graph>");
		}
		return xmlString.toString();
	}

	private static String htmlStart = "<html>\n" +
	"<head>\n" + 
		"<!-- Required CSS --> \n" + 
		"<link type='text/css' rel='stylesheet' href='http://yui.yahooapis.com/2.2.2/build/treeview/assets/tree.css'> \n" + 
		"<!-- Dependency source files -->  \n" + 
		"<script src = 'http://yui.yahooapis.com/2.2.2/build/yahoo/yahoo-min.js' ></script> \n" + 
		"<script src = 'http://yui.yahooapis.com/2.2.2/build/event/event-min.js' ></script> \n" + 
		"<!-- TreeView source file -->  \n" + 
		"<script src = 'http://yui.yahooapis.com/2.2.2/build/treeview/treeview-min.js' ></script>\n" + 
		"<style type='text/css'>" + 
			"a {" + 
				"color: #46546C;" + 
			"}" + 
			"a:hover {" + 
				"color: #4D77C3;" + 
			"}" + 
			"body {" + 
				"font-family: verdana,sans-serif;" + 
			"}" + 
		"</style>\n" + 
		"<title>InvokeVis Tree</title>\n" + 
	"</head>\n" + 
	"<body>\n" + 
		"<div id='treeDiv'></div>\n" + 
		"<script type='text/javascript'>\n" + 
		"//<![CDATA[\n" + 
			"var tree; \n";
	private static String htmlEnd = 
			"YAHOO.util.Event.addListener(window, 'load', treeInit); \n" + 
		"//]]>" + 
		"</script>" + 
	"</body>" + 
"</html>";
	
}
